package com.cysyz.mylib.utils.myassert;

import com.cysyz.mylib.utils.MyReflectionUtils;
import org.springframework.util.Assert;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;


public abstract class MyAssert extends Assert{
    public static <T> void hasNoParamConstructor(Class<T> clazz) {
        MyAssert.notNull(clazz);
        try {
            clazz.getConstructor();
        } catch (Exception e) {
            throw new IllegalArgumentException(clazz.getName() + "必须有一个无参数的构造方法", e);
        }
    }

    public static boolean isNullOrEmpty(Object obj) {
        boolean retValue = false;
        if (obj == null) {
            retValue = true;
        } else if (obj instanceof String && ((String)obj).isEmpty()) {
            retValue = true;
        }
        return retValue;
    }

    public static void checkNullOrEmpty(Object entity, String... fieldNames) {
        MyAssert.notNull(entity);

        List<String> isNullOrEmptyFields = new ArrayList<String>();

        for (String fieldName : fieldNames) {
            Field field = MyReflectionUtils.findField(entity.getClass(), fieldName);
            if (field == null) {
                isNullOrEmptyFields.add(fieldName);
                continue;
            }

            MyReflectionUtils.makeAccessible(field);
            Object value = MyReflectionUtils.getField(field, entity);
            if (value == null) {
                isNullOrEmptyFields.add(fieldName);
                continue;
            } else if (value instanceof String && ((String) value).isEmpty()) {
                isNullOrEmptyFields.add(fieldName);
                continue;
            }
        }
        if (!isNullOrEmptyFields.isEmpty()) {
            throw new InputValueIsNullOrEmptyException(isNullOrEmptyFields, "the value is empty:");
        }
    }

    public static void checkValueEqual(Object entityInput, Object entityDB,
                                       String... fieldNames) throws ValueNotMatchException {
        String entityInputFieldName = null;
        String entityDBFieldName = null;
        List<String> notequalEntityInputFieldNames = new ArrayList<String>();
        for (String fieldName : fieldNames) {
            if (fieldName.contains(":")) {
                String[] twoPart = fieldName.split(":");
                entityInputFieldName = twoPart[0];
                entityDBFieldName = twoPart[1];
            } else {
                entityInputFieldName = fieldName;
                entityDBFieldName = fieldName;
            }
            if (!isEqual(entityInput, entityDB, entityInputFieldName,
                    entityDBFieldName)) {
                notequalEntityInputFieldNames.add(entityInputFieldName);
            }
        }
        if (!notequalEntityInputFieldNames.isEmpty()) {
            throw new ValueNotMatchException(notequalEntityInputFieldNames, "the value is not match");
        }
    }

    private static boolean isEqual(Object entityInput, Object entityDB,
                                   String entityInputFieldName, String entityDBFieldName) {
        Object input = MyReflectionUtils.getFieldValue(entityInputFieldName, entityInput);

        Object db = MyReflectionUtils.getFieldValue(entityDBFieldName, entityDB);
        return input.equals(db);
    }

    public static void notNullMulti(Object... objects ) {
        MyAssert.notNull(objects);
        for (Object object : objects) {
            MyAssert.notNull(object);
        }
    }
}
